package com.culturalyard.service.impl;

import com.culturalyard.constant.ManagementAreaStatusConstant;
import com.culturalyard.constant.MessageConstant;
import com.culturalyard.constant.TopStatusConstant;
import com.culturalyard.exception.CameraNotFoundException;
import com.culturalyard.exception.CameraNotInManagementAreaException;
import com.culturalyard.exception.ParameterException;
import com.culturalyard.mapper.CameraMapper;
import com.culturalyard.pojo.dto.CameraPageQueryDTO;
import com.culturalyard.pojo.entity.Camera;
import com.culturalyard.pojo.vo.CameraPageVO;
import com.culturalyard.pojo.vo.CameraVO;
import com.culturalyard.service.CameraService;
import com.culturalyard.service.OpenApiService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class CameraServiceImpl implements CameraService {
    @Autowired
    private CameraMapper cameraMapper;
    @Autowired
    private OpenApiService openApiServiceImpl;

    /**
     * 根据id查询摄像头信息
     * @param id
     * @return
     */
    @Override
    public CameraVO getByIdWithYardName(String id) {
        return cameraMapper.selectByIdWithYardName(id);
    }

    /**
     * 分页查询监控
     * @param cameraPageQueryDTO
     * @return
     */
    @Override
    public CameraPageVO pageQuery(CameraPageQueryDTO cameraPageQueryDTO) {
        PageHelper.startPage(cameraPageQueryDTO.getPage(), cameraPageQueryDTO.getSize());
        Page<CameraVO> page = cameraMapper.pageQuery(cameraPageQueryDTO);

        // 装配成前端需要的分页结果
        CameraPageVO cameraPageVO = new CameraPageVO();
        cameraPageVO.setPages(page.getPages());
        cameraPageVO.setTotal(page.getTotal());
        cameraPageVO.setPage(cameraPageQueryDTO.getPage());
        cameraPageVO.setSize(cameraPageQueryDTO.getSize());
        cameraPageVO.setRecords(page.getResult());

        return cameraPageVO;
    }

    /**
     * 根据监控id设置置顶状态
     * @param id
     * @param topStatus
     */
    @Override
    @Transactional
    public void updateTopStatusById(String id, Integer topStatus) {
        if (topStatus != TopStatusConstant.TOPPING){
            // 参数校验
            throw new ParameterException(MessageConstant.PARAMETER_ERROR);
        }
        Camera camera;
        if (topStatus == TopStatusConstant.TOPPING){
            // 如果目前已经有置顶摄像头，需要将其取消置顶先
            camera = cameraMapper.selectById(id);
            if (camera == null){
                throw new CameraNotFoundException(MessageConstant.CAMERA_NOT_FOUND);
            }
            // 查看同小院下是否有其他置顶摄像头
            CameraPageQueryDTO cameraPageQueryDTO = new CameraPageQueryDTO();
            cameraPageQueryDTO.setId(camera.getYardId());
            cameraPageQueryDTO.setCameraTopState(TopStatusConstant.TOPPING);
            Page<CameraVO> cameraVOS = cameraMapper.pageQuery(cameraPageQueryDTO);
            camera = new Camera();
            for (CameraVO cameravo:cameraVOS.getResult()){
                camera.setId(cameravo.getId());
                camera.setCameraTopState(TopStatusConstant.NOT_TOPPING);
                cameraMapper.update(camera);
            }
        }
        // 置顶该摄像头
        camera = new Camera();
        camera.setId(id);
        camera.setCameraTopState(topStatus);
        cameraMapper.update(camera);
    }
    /**
     * 根据监控id设置是否在常时监控区
     * @param id
     * @param managementAreaStatus
     */
    @Override
    public void updateManagementAreaStatusById(String id, Integer managementAreaStatus) {
        if (managementAreaStatus != ManagementAreaStatusConstant.EXIST || managementAreaStatus != ManagementAreaStatusConstant.NOT_EXIST){
            throw new ParameterException(MessageConstant.PARAMETER_ERROR);
        }
        Camera camera = new Camera();
        camera.setId(id);
        camera.setCameraManagementAreaState(managementAreaStatus);
        if (managementAreaStatus == ManagementAreaStatusConstant.EXIST){
            camera.setManagementAreaTopTime(new Date());
        }
        cameraMapper.update(camera);
    }

    /**
     * 根据id将已经在常时监控区的摄像头置顶到常时监控区
     * @param id
     * @return
     */
    @Override
    public void updateManagementAreaTopStatusById(String id) {
        // 查询此设备是否在常时监控区
        Camera camera = cameraMapper.selectById(id);
        if (camera.getCameraManagementAreaState() == ManagementAreaStatusConstant.NOT_EXIST){
            throw new CameraNotInManagementAreaException(MessageConstant.CAMERA_NOT_IN_MANAGEMENT_AREA);
        }

        camera = new Camera();
        camera.setId(id);
        camera.setManagementAreaTopTime(new Date());
        cameraMapper.update(camera);
    }

    /**
     * 根据设备id，重新获取该设备的token
     * @param id
     * @return
     */
    @Override
    public String updateTokenById(String id) {
        // 根据id查询设备appkey和secret
        Camera camera = cameraMapper.selectById(id);

        // 根据appKey和secret查询token
        String token = openApiServiceImpl.getAccessToken(camera.getAppKey(), camera.getSecret());
        camera.setToken(token);

        // 更新数据库token数据
        cameraMapper.update(camera);
        return token;
    }

    /**
     * 查看所有常时监控区的摄像头
     * @return
     */
    @Override
    public List<CameraVO> listManagementArea() {
        return cameraMapper.selectManagementArea(ManagementAreaStatusConstant.EXIST);
    }

    /**
     * 分页查看在常时监控区的摄像头
     * @param page
     * @param size
     * @return
     */
    @Override
    public CameraPageVO pageManagementArea(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        Page<CameraVO> cameraVOS = cameraMapper.pageManagementArea(ManagementAreaStatusConstant.EXIST);

        // 装配成前端需要的分页结果
        CameraPageVO cameraPageVO = new CameraPageVO();
        cameraPageVO.setPages(cameraVOS.getPages());
        cameraPageVO.setTotal(cameraVOS.getTotal());
        cameraPageVO.setPage(page);
        cameraPageVO.setSize(size);
        cameraPageVO.setRecords(cameraVOS.getResult());

        return cameraPageVO;
    }



}
